from sqlalchemy import Column, String, Integer, PickleType, DateTime, Interval
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relation
from sqlalchemy.orm.collections import attribute_mapped_collection
from sc.model.meta import Base, Session



class League(Base):
    __tablename__ = 'leagues'

    name_key = Column(String(30), primary_key=True)
    name = Column(String(40))
    stages = relation('LeagueStage',
            collection_class=attribute_mapped_collection('name_key'))
    # HACK: Still needed?
    matches = []

    def __init__(self, name_key):
        self.name_key = name_key


class LeagueStage(Base):
    __tablename__ = 'league_stages'

    # Columns
    id = Column(Integer, primary_key=True)
    name_key = Column(String(20))
    name = Column(String(30))

    format = Column(PickleType)
    start_date = Column(DateTime)
    end_date = Column(DateTime)

    # Foreign Keys
    league_id = Column(String(30), ForeignKey("leagues.name_key"))
    stage_id = Column(Integer, ForeignKey("league_stages.id"))

    # Relationships
    stages = relation('LeagueStage',
            collection_class=attribute_mapped_collection('name_key'))
    matches = relation('Match',
            collection_class=attribute_mapped_collection('id'))
    
    def __init__(self, name_key):
        self.name_key = name_key

class Match(Base):
    __tablename__ = 'matches'

    # Columns
    id = Column(Integer, primary_key=True)
    discriminator = Column('type', String(50))

    # Foreign Keys
    stage_id = Column(Integer, ForeignKey("league_stages.id"))
    games = relation('Game',
            collection_class=attribute_mapped_collection('game_number'))

    __mapper_args__ = {'polymorphic_on' : discriminator}

    def __init__(self, match_id):
        self.id = match_id

class ProleagueMatch(Match):
    __tablename__ = 'proleague_matches'
    __mapper_args__ = {'polymorphic_identity' : 'proleague_match'}
    # Columns
    id = Column(Integer, ForeignKey('matches.id'), primary_key=True)

    winner_score = Column(Integer)
    loser_score = Column(Integer)

    team_one_id = Column(Integer, ForeignKey("teams.id"))
    team_two_id = Column(Integer, ForeignKey("teams.id"))
    winner_id = Column(Integer, ForeignKey("teams.id"))

    # Relationships
    team_one = relation('Team', primaryjoin='ProleagueMatch.team_one_id == Team.id')
    team_two = relation('Team', primaryjoin='ProleagueMatch.team_two_id == Team.id')
    winner = relation('Team', primaryjoin='ProleagueMatch.winner_id == Team.id')

class Game(Base):
    __tablename__ = 'games'

    # Columns
    id = Column(Integer, primary_key=True)
    game_number = Column(Integer)
    player_one_start_location = Column(Integer)
    player_two_start_location = Column(Integer)
    date_played = Column(DateTime)
    playtime = Column(Interval)

    # Foreign Keys
    match_id = Column(Integer, ForeignKey('matches.id'))
    player_one_id = Column(Integer, ForeignKey('players.id'))
    player_two_id = Column(Integer, ForeignKey('players.id'))
    game_map_id = Column(Integer, ForeignKey('maps.id'))
    winner_id = Column(Integer, ForeignKey('players.id'))

    # Relationships
    player_one = relation('Player', primaryjoin='Game.player_one_id == Player.id')
    player_two = relation('Player', primaryjoin='Game.player_two_id == Player.id')
    game_map = relation('Map', primaryjoin='Game.game_map_id == Map.id')
    winner = relation('Player', primaryjoin='Game.winner_id == Player.id')
    commentary_sets = relation('CommentarySet',
        collection_class=attribute_mapped_collection('author'))
    
    def __init__(self, match_id, game_number):
        self.match_id = match_id
        self.game_number = game_number

class Team(Base):
    __tablename__ = 'teams'
    id = Column(Integer, primary_key=True)
    name_key = Column(String(20))
    name = Column(String(30))

    def __init__(self, id):
        self.id = id

class Player(Base):
    __tablename__ = 'players'
    id = Column(Integer, primary_key=True)
    name = Column(String(30))
    race = Column(String(1))

    def __init__(self, id):
        self.id = id

class Map(Base):
    __tablename__ = 'maps'

    id = Column(Integer, primary_key=True)
    name = Column(String(30))
    version = Column(String(10))

    def __init__(self, id):
        self.id = id

    @property
    def full_name(self):
        if self.version == '1.0':
            return self.name
        else:
            return '%s (%s)' % (self.name, self.version)

class CommentarySet(Base):
    __tablename__ = 'commentary_sets'

    # Columns
    id = Column(Integer, primary_key=True)
    author = Column(String)
    video_ids = Column(PickleType)

    # Foreign Keys
    game_id = Column(Integer, ForeignKey('games.id'))

    def __init__(self, author):
        self.author = author
        self.video_ids = []
